package com.lap.framework.dto.result;

import com.lap.framework.constant.Header;
import com.lap.framework.enums.SystemCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.ToString;
import org.slf4j.MDC;

/**
 * 统一返回结果对象,这里不提供 Result<T>(String errMsg) 构造函数，防止跟数据构造函数冲突
 *
 * @param <T> 类型
 * @author Shuisheng Lao(劳水生)
 * @version 0.0.1
 */
@ToString
@Getter
@Schema(description = "返回结果")
public class Result<T> {
  /** 状态码,参考: {@link SystemCode} */
  @Schema(description = "状态码")
  private int code;

  @Schema(description = "默认信息")
  private String message;

  @Schema(description = "返回数据")
  private T data;

  @Schema(description = "链路追踪")
  private String requestId;

  @Schema(description = "时间戳")
  private final Long timestamp = java.lang.System.currentTimeMillis();

  private Result() {
    this(SystemCode.SUCCESS);
  }

  private Result(ErrorCode errorCode, T data) {
    this(errorCode);
    this.data = data;
  }

  private Result(ErrorCode errorCode) {
    this(errorCode, errorCode.getMessageKey());
  }

  private Result(ErrorCode errorCode, String newMsg) {
    this.code = errorCode.getExternalCode();
    this.message = newMsg;
    this.requestId = MDC.get(Header.REQUEST_ID);
  }

  /**
   * 静态成功创建工厂
   *
   * @return 成功类型
   * @param <R> 类型
   */
  public static <R> Result<R> ok() {
    return new Result<>(SystemCode.SUCCESS);
  }

  /**
   * 静态成功创建工厂
   *
   * @param <R> 返回类型
   * @param data 返回结果
   * @return 返回结果
   */
  public static <R> Result<R> ok(R data) {
    return new Result<>(SystemCode.SUCCESS, data);
  }

  /**
   * 静态失败创建工厂
   *
   * @param <R> 返回类型
   * @param errorCode 信息提示
   * @return 返回结果
   */
  public static <R> Result<R> fail(ErrorCode errorCode) {
    return new Result<>(errorCode);
  }

  /**
   * 静态失败创建工厂
   *
   * @param <R> 返回类型
   * @param errorCode 信息提示
   * @param newMessage 新信息
   * @return 返回结果
   */
  public static <R> Result<R> fail(ErrorCode errorCode, String newMessage) {
    return new Result<>(errorCode, newMessage);
  }
}
